package nac.tanke;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Stage extends Canvas {

  private BufferStrategy strategy;
  private boolean gameRunning = true;
  private ArrayList entities = new ArrayList();
  private ArrayList removeList = new ArrayList();
  private JFrame container;
  private boolean upPressed = false;
  private boolean downPressed = false;
  private boolean leftPressed = false;
  private boolean rightPressed = false;
  private boolean firePressed = false;
  private int moveSpeed = 100;
  private Tank tank;

  public Stage() {

    container = new JFrame("Tanke");
    JPanel panel = (JPanel) container.getContentPane();
    panel.setPreferredSize(new Dimension(480, 480));
    panel.setLayout(null);
    panel.add(this);
    setBounds(0, 0, 480, 480);
    setIgnoreRepaint(true);
    container.pack();
    container.setResizable(false);
    container.setVisible(true);
    container.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    addKeyListener(new KeyInputHandler());

    requestFocus();
    createBufferStrategy(2);
    strategy = getBufferStrategy();
    initEntities();
  }

  private void initEntities() {
    tank = new Tank(this, "natz", 200, 200, 30, 30);
    entities.add(tank);
  }

  public void removeEntity(Entity entity) {
    removeList.add(entity);
  }

  public void gameLoop() {
    long lastLoopTime = System.currentTimeMillis();

    while (gameRunning) {
      long delta = System.currentTimeMillis() - lastLoopTime;
      lastLoopTime = System.currentTimeMillis();

      Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
      g.setColor(Color.black);
      g.fillRect(0, 0, 480, 480);

      for (int i = 0; i < entities.size(); i++) {
        Entity entity = (Entity) entities.get(i);
        entity.move(delta);
      }

      for (int i = 0; i < entities.size(); i++) {
        Entity entity = (Entity) entities.get(i);
        entity.draw(g);
      }

      for (int p = 0; p < entities.size(); p++) {
        for (int s = p + 1; s < entities.size(); s++) {
          Entity me = (Entity) entities.get(p);
          Entity him = (Entity) entities.get(s);

          if (me.collidesWith(him)) {
            me.collidedWith(him);
            him.collidedWith(me);
          }
        }
      }

      entities.removeAll(removeList);
      removeList.clear();
      for (int i = 0; i < entities.size(); i++) {
        Entity entity = (Entity) entities.get(i);
        entity.doLogic();
      }

      g.dispose();
      strategy.show();

      if (leftPressed) {
        tank.getVector().x = -moveSpeed;
      } else if (rightPressed) {
        tank.getVector().x = moveSpeed;
      } else if (upPressed) {
        tank.getVector().y = -moveSpeed;
      } else if (downPressed) {
        tank.getVector().y = moveSpeed;
      }

      long sleepTime = lastLoopTime + 10 - System.currentTimeMillis();
      try {
        Thread.sleep(sleepTime < 0 ? 0 : sleepTime);
      } catch (InterruptedException ex) {
      }
    }
  }

  private class KeyInputHandler extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_A) {
        leftPressed = true;
      }
      if (e.getKeyCode() == KeyEvent.VK_D) {
        rightPressed = true;
      }

      if (e.getKeyCode() == KeyEvent.VK_W) {
        upPressed = true;
      }

      if (e.getKeyCode() == KeyEvent.VK_S) {
        downPressed = true;
      }
      if (e.getKeyCode() == KeyEvent.VK_SPACE) {
        firePressed = true;
      }
    }

    @Override
    public void keyReleased(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_A) {
        leftPressed = false;
      }
      if (e.getKeyCode() == KeyEvent.VK_D) {
        rightPressed = false;
      }

      if (e.getKeyCode() == KeyEvent.VK_W) {
        upPressed = false;
      }
      if (e.getKeyCode() == KeyEvent.VK_S) {
        downPressed = false;
      }
      if (e.getKeyCode() == KeyEvent.VK_SPACE) {
        firePressed = false;
      }
    }
  }

  public static void main(String[] args) {
    Stage stage = new Stage();
    stage.gameLoop();
  }
}
